import { Injectable, Logger } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository, LessThan } from "typeorm";
import {
  CasinoChibiRound,
  ChibiRoundStatus,
} from "../entities/casino-chibi-round.entity";

@Injectable()
export class CasinoChibiRoundService {
  private readonly logger = new Logger(CasinoChibiRoundService.name);

  constructor(
    @InjectRepository(CasinoChibiRound)
    private readonly roundRepository: Repository<CasinoChibiRound>
  ) { }

  /**
   * 获取当前活跃期数
   */
  async getCurrentRound(): Promise<CasinoChibiRound | null> {
    try {
      return await this.roundRepository.findOne({
        where: { status: ChibiRoundStatus.BETTING },
        order: { id: "DESC" },
      });
    } catch (error) {
      this.logger.error(
        `获取当前期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return null;
    }
  }

  /**
   * 获取最新期数
   */
  async getLastRound(): Promise<CasinoChibiRound | null> {
    try {
      return await this.roundRepository.findOne({
        where: {}, // 添加空的 where 条件
        order: { id: "DESC" },
      });
    } catch (error) {
      this.logger.error(
        `获取最新期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return null;
    }
  }

  /**
   * 获取最新已结算期数
   */
  async getLatestSettledRound(): Promise<CasinoChibiRound | null> {
    try {
      return await this.roundRepository.findOne({
        where: { status: ChibiRoundStatus.SETTLED },
        order: { id: "DESC" },
        // relations: ["chibiBets"], // 已移除外键关联
      });
    } catch (error) {
      this.logger.error(
        `获取最新已结算期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return null;
    }
  }

  /**
   * 根据期数ID获取期数
   */
  async getRoundById(roundId: number): Promise<CasinoChibiRound | null> {
    try {
      return await this.roundRepository.findOne({
        where: { id: roundId },
        // relations: ["chibiBets"], // 已移除外键关联
      });
    } catch (error) {
      this.logger.error(
        `根据期数ID获取期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return null;
    }
  }

  /**
   * 创建新期数
   */
  async createNewRound(
    startTime: Date,
    endTime: Date
  ): Promise<CasinoChibiRound> {
    try {
      const newRound = this.roundRepository.create({
        startTime,
        endTime,
        status: ChibiRoundStatus.BETTING,
        weiTotalGold: 0,
        weiTotalSilver: 0,
        shuTotalGold: 0,
        shuTotalSilver: 0,
        wuTotalGold: 0,
        wuTotalSilver: 0,
      });

      const savedRound = await this.roundRepository.save(newRound);
      this.logger.log(`创建赤壁玩法新期数: ${savedRound.id}`);
      return savedRound;
    } catch (error) {
      this.logger.error(
        `创建新期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 关闭期数
   */
  async closeRound(roundId: number): Promise<void> {
    try {
      const round = await this.roundRepository.findOne({
        where: { id: roundId },
      });
      if (!round) {
        throw new Error("期数不存在");
      }

      round.status = ChibiRoundStatus.DRAWING;
      await this.roundRepository.save(round);
      this.logger.log(`期数 ${roundId} 已关闭，状态更新为开奖中`);
    } catch (error) {
      this.logger.error(
        `关闭期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 结算期数
   */
  async settleRound(roundId: number): Promise<void> {
    try {
      const round = await this.roundRepository.findOne({
        where: { id: roundId },
      });
      if (!round) {
        throw new Error("期数不存在");
      }

      round.status = ChibiRoundStatus.SETTLED;
      await this.roundRepository.save(round);
      this.logger.log(`期数 ${roundId} 已结算`);
    } catch (error) {
      this.logger.error(
        `结算期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 获取历史期数
   */
  async getHistoryRounds(
    page: number = 0,
    pageSize: number = 20
  ): Promise<{ rounds: CasinoChibiRound[]; total: number }> {
    try {
      const [rounds, total] = await this.roundRepository.findAndCount({
        order: { id: "DESC" },
        skip: page * pageSize,
        take: pageSize,
      });

      return { rounds, total };
    } catch (error) {
      this.logger.error(
        `获取历史期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return { rounds: [], total: 0 };
    }
  }

  /**
   * 更新期数统计信息
   */
  async updateRoundStats(
    roundId: number,
    weiTotalGold: number,
    weiTotalSilver: number,
    shuTotalGold: number,
    shuTotalSilver: number,
    wuTotalGold: number,
    wuTotalSilver: number
  ): Promise<void> {
    try {
      await this.roundRepository.update(roundId, {
        weiTotalGold,
        weiTotalSilver,
        shuTotalGold,
        shuTotalSilver,
        wuTotalGold,
        wuTotalSilver,
      });
    } catch (error) {
      this.logger.error(
        `更新期数统计失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
    }
  }

  /**
   * 获取需要结算的期数
   * 确保期数为已开奖状态，并且有开奖结果（获胜国家已确定）
   */
  async getRoundsToSettle(): Promise<CasinoChibiRound[]> {
    try {
      // 查询状态为已开奖的期数
      const rounds = await this.roundRepository.find({
        where: { status: ChibiRoundStatus.DRAWING },
        order: { id: "ASC" },
      });

      // 过滤出有开奖结果的期数（获胜国家已确定）
      const validRounds = rounds.filter(round =>
        round.winningSide !== null &&
        round.winningSide !== undefined &&
        round.winningSide >= 1 &&
        round.winningSide <= 3
      );

      this.logger.log(
        `找到 ${rounds.length} 个开奖中赤壁期数，其中 ${validRounds.length} 个有开奖结果`
      );

      return validRounds;
    } catch (error) {
      this.logger.error(
        `获取需要结算的期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return [];
    }
  }

  /**
   * 清理过期期数
   */
  async cleanupExpiredRounds(daysToKeep: number = 30): Promise<number> {
    try {
      const cutoffDate = new Date();
      cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);

      const result = await this.roundRepository
        .createQueryBuilder()
        .delete()
        .from(CasinoChibiRound)
        .where("created_at < :cutoffDate", { cutoffDate })
        .andWhere("status = :status", { status: ChibiRoundStatus.SETTLED })
        .execute();

      return result.affected || 0;
    } catch (error) {
      this.logger.error(
        `清理过期期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return 0;
    }
  }

  /**
   * 获取过期但仍在下注状态的期数
   */
  async getExpiredActiveRounds(): Promise<CasinoChibiRound[]> {
    try {
      const now = new Date();
      return await this.roundRepository.find({
        where: {
          status: ChibiRoundStatus.BETTING,
          endTime: LessThan(now),
        },
      });
    } catch (error) {
      this.logger.error(
        `获取过期活跃期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return [];
    }
  }

  /**
   * 获取所有活跃期数（下注中状态）
   */
  async getAllActiveRounds(): Promise<CasinoChibiRound[]> {
    try {
      return await this.roundRepository.find({
        where: {
          status: ChibiRoundStatus.BETTING,
        },
      });
    } catch (error) {
      this.logger.error(
        `获取所有活跃期数失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      return [];
    }
  }

  /**
   * 更新期数状态
   */
  async updateRoundStatus(
    roundId: number,
    status: number,
    gameType?: any // 兼容参数，但不使用
  ): Promise<void> {
    try {
      const round = await this.roundRepository.findOne({
        where: { id: roundId },
      });
      if (!round) {
        throw new Error("期数不存在");
      }

      // 根据状态执行相应操作
      switch (status) {
        case ChibiRoundStatus.DRAWING:
          await this.closeRound(roundId);
          break;
        case ChibiRoundStatus.SETTLED:
          await this.settleRound(roundId);
          break;
        default:
          throw new Error("不支持的状态值");
      }
    } catch (error) {
      this.logger.error(
        `更新期数状态失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 更新期数时间
   */
  async updateRoundTimes(
    roundId: number,
    startTime: Date,
    endTime: Date
  ): Promise<void> {
    try {
      const round = await this.roundRepository.findOne({
        where: { id: roundId },
      });
      if (!round) {
        throw new Error("期数不存在");
      }

      // 更新期数时间
      round.startTime = startTime;
      round.endTime = endTime;

      await this.roundRepository.save(round);
      this.logger.log(
        `✅ 更新赤壁玩法期数 ${roundId} 时间成功: 开始=${startTime.toISOString()}, 结束=${endTime.toISOString()}`
      );
    } catch (error) {
      this.logger.error(
        `更新期数时间失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 更新期数开奖结果
   */
  async updateRoundResult(roundId: number, result: any): Promise<void> {
    try {
      const round = await this.roundRepository.findOne({
        where: { id: roundId },
      });
      if (!round) {
        throw new Error("期数不存在");
      }

      // 更新开奖结果
      round.winningSide = result.winningSide;
      round.battleReport = result.battleReport || result.reportStr;
      round.reportStr = result.reportStr || result.battleReport;

      await this.roundRepository.save(round);
      this.logger.log(
        `✅ 更新赤壁玩法期数 ${roundId} 开奖结果成功: 获胜方=${this.getSideName(
          result.winningSide
        )}`
      );
    } catch (error) {
      this.logger.error(
        `更新期数开奖结果失败: ${error instanceof Error ? error.message : String(error)
        }`
      );
      throw error;
    }
  }

  /**
   * 获取国家名称
   */
  private getSideName(side: number): string {
    const sideNames: Record<number, string> = {
      1: "魏国",
      2: "蜀国",
      3: "吴国",
    };
    return sideNames[side] || "未知";
  }
}
